package com.jas.ui;
//@author A0098803W
import java.util.ArrayList;
import java.util.TreeMap;

import com.jas.common.CommandFormatException;
import com.jas.common.DateFormatException;
import com.jas.common.DeadlineEvent;
import com.jas.common.Event;
import com.jas.common.EventDateException;
import com.jas.common.Language;
import com.jas.common.Notification;
import com.jas.common.SearchException;
import com.jas.common.TimedEvent;
import com.jas.common.Utilities;
import com.jas.logic.EventIdException;
import com.jas.logic.LogicAPI;
import com.jas.storage.StorageException;

//@author A0098803W
/**
 * This class handles the communication with the <code>LogicAPI</code> class.
 * 
 */
public class DisplayControl {

	LogicAPI logicAPI;
	TreeMap<String, CommandType> mappingOfCommandsToCommandTypes;
	TreeMap<Integer, String> mappingOfDisplayedIndexToEventId;
	private TreeMap<Integer, Notification> mappingOfDisplayedIndexToNotificationObj;
	private boolean newNotification = false;
	private boolean lastActionRestored = false;

	//@author A0098803W
	/**
	 * These are the possible command types
	 * 
	 * 
	 */
	enum CommandType {
		UNDO, SMS, NOTIFY, CHANGE_LANGUAGE, ADD_TASK, DELETE_TASK, SHOW_TASKS_IN_CLI, EXIT, INVALID, SEARCH, UPDATE_TASK
	};

	/**
	 * This constructor initialises DisplayControl object.
	 * 
	 * @param args
	 *            User's input parameter.
	 */
	// @author a0118677
	public DisplayControl(LogicAPI logicAPI) {
		this.logicAPI = logicAPI;
		mappingOfDisplayedIndexToEventId = new TreeMap<Integer, String>();
		mappingOfCommandsToCommandTypes = new TreeMap<String, CommandType>();
		mappingOfDisplayedIndexToNotificationObj = new TreeMap<Integer, Notification>();
		addCommands();
	}

	public DisplayControl() {

		mappingOfDisplayedIndexToEventId = new TreeMap<Integer, String>();
		mappingOfCommandsToCommandTypes = new TreeMap<String, CommandType>();
		mappingOfDisplayedIndexToNotificationObj = new TreeMap<Integer, Notification>();
		addCommands();
	}

	//@author A0098803W
	/**
	 * This method executes any command entered by the user.
	 * 
	 * @param input
	 *            User's command
	 * @throws CommandFormatException
	 * @throws StorageException
	 * @throws EventIdException
	 * @throws DateFormatException
	 * @throws SearchException
	 * @throws EventDateException
	 */
	public void executeUserCommand(String input) throws CommandFormatException,
			StorageException, EventIdException, DateFormatException,
			SearchException, EventDateException {
		// get command entered by user
		String userCommand = getFirstWord(input);
		// extract the text
		String sentence = removeFirstWord(input);
		// execute the command
		CommandType commandType = determineCommandType(userCommand);
		ArrayList<Event> sortedEventList;
		ArrayList<String> extractedSequence;
		switch (commandType) {
		case ADD_TASK:
			ArrayList<Event> addedEvent = logicAPI.add(sentence);
			System.out.println(Language.getString("SUCCESSFULL_ADD"));

			showDetailedListOfEvents(addedEvent, false);
			lastActionRestored = false;
			break;
		case DELETE_TASK:
			extractedSequence = checkValidSerialNumbers(sentence);
			if (extractedSequence.isEmpty() == true) {
				performDeleteForSingleSerialNumber(sentence);
			} else {
				performDeleteForMultipleSerialNumbers(extractedSequence);
				lastActionRestored = false;
			}
			break;
		case UPDATE_TASK:

			ArrayList<Event> updatedEvents;
			try {
				if (sentence.length() > 0) {
					int displayedIndex = Integer
							.parseInt(getFirstWord(sentence));
					if (mappingOfDisplayedIndexToEventId
							.containsKey(displayedIndex)) {
						String eventId = mappingOfDisplayedIndexToEventId
								.get(displayedIndex);
						updatedEvents = logicAPI.update(eventId,
								removeFirstWord(sentence));
						System.out.println(Language
								.getString("SUCCESSFULL_UPDATE"));

						assert (updatedEvents.size() == 1);
						
						showDetailedListOfEvents(updatedEvents, false);
						lastActionRestored = false;
					} else {
						throw new EventIdException(String.format(
								Language.getString("ERROR_WRONG_INDEX"),
								displayedIndex));
					}
				} else {
					throw new CommandFormatException("");
				}
			} catch (NumberFormatException e) {
				throw new CommandFormatException("ERROR_MUST_START_WITH_INDEX");
			}
			break;
		case SHOW_TASKS_IN_CLI:
			if (sentence.startsWith("#")) {
				showDetailsOfEventsFromListofSerialNumbers(sentence);
			} else {
				ArrayList<Event> eventsToDisplay = logicAPI.display(sentence);
				showListOfEvents(eventsToDisplay, true);
			}
			break;
		case CHANGE_LANGUAGE:

			Language.currentLanguage = sentence.toLowerCase();
			Language.loadLanguageFile();
			addCommands();
			logicAPI.updateLanguage();
			break;
		case EXIT:
			System.exit(0);
		case INVALID:
			throw new CommandFormatException(
					Language.getString("ERROR_UNRECOGNISED_COMMAND"));
		case SEARCH:
			performSearchOnUserInput(sentence);

			break;
		case NOTIFY:
			sentence.trim();
			if (!sentence.startsWith("@") && !sentence.equalsIgnoreCase("u")
					|| sentence.isEmpty()) {
				throw new CommandFormatException(
						Language.getString("ERROR_UNRECOGNISED_COMMAND"));
			} else if (sentence.equalsIgnoreCase("u")) {
				undoAddNewNotification();
			} else {
				addNotification(sentence);
			}

			break;
		case SMS:
			updateMessageGateway(sentence);
			break;
		case UNDO:
			if (!lastActionRestored) {
				logicAPI.undo();
				lastActionRestored = true;
				System.out.println(Language.getString("SUCCESSFUL_UNDO"));
			}
			else{
				throw new CommandFormatException(
						Language.getString("ERROR_UNDO_FAILED"));
			}
			
			break;
		default:
			throw new CommandFormatException(
					Language.getString("ERROR_UNRECOGNISED_COMMAND"));
		}
	}

	//@author a0118677r
	private void showListOfEvents(ArrayList<Event> eventList,
			boolean withIndexing) {
		mappingOfDisplayedIndexToEventId.clear();
		System.out.println(Language.getString("DISPLAY_LIST_TOP"));
		System.out.println(Language.getString("DISPLAY_LIST_HEADER"));
		System.out.println(Language.getString("DISPLAY_LIST_SEPARATOR"));
		int counter = 0;
		for (Event event : eventList) {
			counter++;
			System.out.printf(Language.getString("DISPLAY_LIST_COUNTER"),
					counter);
			System.out.println(event.toString());
			mappingOfDisplayedIndexToEventId.put(counter, event.getEventId());
		}
		System.out.println(Language.getString("DISPLAY_LIST_FOOTER"));
	}

	//@author A0098803W
	/**
	 * This method shows a detailed description of an event.
	 * 
	 * @param eventList
	 *            List containing <code>Event</code> type objects.
	 * @param clearList
	 *            <code>true</code> to clear current index list
	 *            <code>false</code> if otherwise.
	 */
	private void showDetailedListOfEvents(ArrayList<Event> eventList,
			boolean withIndexing) {
		if (withIndexing == true) {
			mappingOfDisplayedIndexToEventId.clear();
		}
		String eventId = "";
		String eventStartDateTime = "";
		String eventEndDateTime = "";
		String completionStatus = "";
		String description = "";
		int counter = 0;
		for (Event event : eventList) {
			counter++;
			eventId = event.getEventId();
			description = event.getEventDescription();
			
			if (event.isCompleted() == true) {
				completionStatus = Language.getString("KEYWORD_YES");
			} else {
				completionStatus = Language.getString("KEYWORD_NO");
			}
			if (event instanceof TimedEvent) {
				eventStartDateTime = Utilities.calendarToString(
						((TimedEvent) event).getEventStartDateTime(),
						Language.getString("SEARCH_DATE_TIME_FORMAT"));
				eventEndDateTime = Utilities.calendarToString(
						((TimedEvent) event).getEventEndDateTime(),
						Language.getString("SEARCH_DATE_TIME_FORMAT"));
			} else if (event instanceof DeadlineEvent) {
				eventEndDateTime = Utilities.calendarToString(
						((DeadlineEvent) event).getEventEndDateTime(),
						Language.getString("SEARCH_DATE_TIME_FORMAT"));
			}
			if (withIndexing == true) {
				mappingOfDisplayedIndexToEventId.put(counter,
						event.getEventId());
			}
			System.out.printf(Language.getString("SHOW_LIST_TOP"));
			System.out.printf(Language.getString("SHOW_LIST_SERIAL_NUMBER"),
					counter);
			System.out.printf(Language.getString("SHOW_LIST_EVENTID"), eventId);
			System.out.printf(
					Language.getString("SHOW_LIST_EVENT_START_DATETIME"),
					eventStartDateTime);
			System.out.printf(
					Language.getString("SHOW_LIST_EVENT_END_DATETIME"),
					eventEndDateTime);
			System.out.printf(Language.getString("SHOW_LIST_EVENT_COMPLETION"),
					completionStatus);
			System.out.printf(Language.getString("SHOW_DESCRIPTION"),
					description);
			System.out.printf(Language.getString("SHOW_FOOTER"), description);
		}

	}

	//@author A0098803W
	/**
	 * This method searches storage for the text user entered.
	 * 
	 * @param sentence
	 *            User text
	 * @throws SearchException
	 * @throws DateFormatException
	 */
	private void performSearchOnUserInput(String sentence)
			throws SearchException, DateFormatException {
		ArrayList<Event> matchingList = logicAPI.search(sentence);

		if (matchingList.isEmpty()) {
			throw new SearchException(
					Language.getString("ERROR_SEARCH_NOT_FOUND"));
		} else {
			if (matchingList.size() == 1) {
				showDetailedListOfEvents(matchingList, true);
			} else {
				ArrayList<Event> sortedEventList = Utilities.sortList(
						matchingList, Language.getString("SHOW_ASCENDING"));
				showListOfEvents(sortedEventList, true);
			}
		}
	}

	//@author A0098803W
	/**
	 * This method is executed if user enters for example,<br>
	 * <br>
	 * <code>del 1</code> <br>
	 * <br>
	 * For the above command, 1 is the serial number for recently displayed
	 * list.
	 * 
	 * @param sentence
	 *            User text
	 * @throws StorageException
	 * @throws EventIdException
	 */
	private void performDeleteForSingleSerialNumber(String sentence)
			throws StorageException, EventIdException {
		ArrayList<Event> deletedEvents = new ArrayList<Event>();
		try {

			int displayedIndex = Integer.parseInt(sentence);
			if (mappingOfDisplayedIndexToEventId.containsKey(displayedIndex)) {
				String eventId = mappingOfDisplayedIndexToEventId
						.get(displayedIndex);
				deletedEvents = logicAPI.delete(eventId);
			} else {
				deletedEvents = logicAPI.delete(sentence);
			}
		} catch (NumberFormatException e) {
			deletedEvents = logicAPI.delete(sentence);
		}
		System.out.println(Language.getString("SUCCESSFULL_DELETE"));

		showDetailedListOfEvents(deletedEvents, true);
	}

	//@author A0098803W
	/**
	 * This method is executed if user enters for example,<br>
	 * <br>
	 * <code>del 1-3,5,7</code> <br>
	 * <br>
	 * For the above command, 1 is the serial number for recently displayed
	 * list.
	 * 
	 * @param extractedSequence
	 *            Extracted list of serial numbers entered by the user.
	 * @throws StorageException
	 * @throws EventIdException
	 */
	private void performDeleteForMultipleSerialNumbers(
			ArrayList<String> extractedSequence) throws StorageException,
			EventIdException {
		ArrayList<Event> deletedEvents = new ArrayList<Event>();
		ArrayList<Event> finalDeletedList = new ArrayList<Event>();
		for (String deleteList : extractedSequence) {
			try {
				int displayedIndex = Integer.parseInt(deleteList);
				if (mappingOfDisplayedIndexToEventId
						.containsKey(displayedIndex)) {
					String eventId = mappingOfDisplayedIndexToEventId
							.get(displayedIndex);
					deletedEvents = logicAPI.delete(eventId);

				}
			} catch (NumberFormatException e) {
				deletedEvents = logicAPI.delete(deleteList);
			}

			for (Event event : deletedEvents) {
				finalDeletedList.add(event);

			}
			deletedEvents.clear();

		}
		System.out.println(Language.getString("SUCCESSFULL_DELETE"));

		showDetailedListOfEvents(finalDeletedList, true);

	}

	//@author A0098803W
	/**
	 * This method is executed if user enters for example,<br>
	 * <br>
	 * <code>show #1</code> <br>
	 * <br>
	 * <code>show #1,2,3</code> <br>
	 * <br>
	 * These numbers are from the serial numbers recently displayed.
	 * 
	 * @param sentence
	 *            User text
	 * @throws CommandFormatException
	 * @throws DateFormatException
	 * @throws SearchException
	 */
	private void showDetailsOfEventsFromListofSerialNumbers(String sentence)
			throws CommandFormatException, DateFormatException, SearchException {

		sentence = extractShowCommandFromUser(sentence);
		if (sentence.isEmpty()) {
			throw new CommandFormatException(
					Language.getString("ERROR_UNRECOGNISED_COMMAND"));
		}
		ArrayList<String> extractedSequence = checkValidSerialNumbers(sentence);
		if (extractedSequence.isEmpty() == true) {
			showDetailsOfEventFromSingleSerialNumber(sentence);

		} else {
			showDetailsOfEventsFromMultipleSerialNumbers(extractedSequence);
		}
	}

	//@author A0098803W
	/**
	 * This method is executed if user enters for example,<br>
	 * <br>
	 * <code>show #1</code> <br>
	 * <br>
	 * This is from the serial number recently displayed.
	 * 
	 * @param sentence
	 *            User text
	 * @throws CommandFormatException
	 * @throws DateFormatException
	 * @throws SearchException
	 */
	private void showDetailsOfEventFromSingleSerialNumber(String sentence)
			throws CommandFormatException, DateFormatException, SearchException {
		ArrayList<Event> eventsToDisplay = new ArrayList<Event>();
		try {

			int displayedIndex = Integer.parseInt(sentence);
			if (mappingOfDisplayedIndexToEventId.containsKey(displayedIndex)) {
				String eventId = mappingOfDisplayedIndexToEventId
						.get(displayedIndex);
				eventsToDisplay = logicAPI.display(eventId);
			} else {
				eventsToDisplay = logicAPI.display(sentence);
			}
		} catch (NumberFormatException e) {
			throw new CommandFormatException(
					Language.getString("ERROR_UNRECOGNISED_COMMAND"));
		}
		if (eventsToDisplay.isEmpty()) {
			throw new SearchException(
					Language.getString("ERROR_SEARCH_NOT_FOUND"));
		} else {
			showDetailedListOfEvents(eventsToDisplay, false);
		}
	}

	//@author A0098803W
	/**
	 * This method is executed if user enters for example,<br>
	 * <br>
	 * <code>show #1,2,3</code> <br>
	 * <br>
	 * These numbers are from the serial numbers recently displayed.
	 * 
	 * @param extractedSequence
	 *            The list of serial numbers
	 * @throws CommandFormatException
	 * @throws DateFormatException
	 * @throws SearchException
	 */
	private void showDetailsOfEventsFromMultipleSerialNumbers(
			ArrayList<String> extractedSequence) throws CommandFormatException,
			DateFormatException, SearchException {

		ArrayList<Event> eventsToDisplay = new ArrayList<Event>();
		ArrayList<Event> finalEventsToDisplayList = new ArrayList<Event>();
		for (String displayShowList : extractedSequence) {
			try {
				int displayedIndex = Integer.parseInt(displayShowList);
				if (mappingOfDisplayedIndexToEventId
						.containsKey(displayedIndex)) {
					String eventId = mappingOfDisplayedIndexToEventId
							.get(displayedIndex);
					eventsToDisplay = logicAPI.display(eventId);

				}
			} catch (NumberFormatException e) {
				throw new CommandFormatException(
						Language.getString("ERROR_UNRECOGNISED_COMMAND"));
			}

			for (Event event : eventsToDisplay) {
				finalEventsToDisplayList.add(event);

			}
			eventsToDisplay.clear();

		}
		if (finalEventsToDisplayList.isEmpty()) {
			throw new SearchException(
					Language.getString("ERROR_SEARCH_NOT_FOUND"));
		} else {
			showDetailedListOfEvents(finalEventsToDisplayList, false);
		}
	}

	/**
	 * This method defines the commands available to the user.
	 * 
	 * @param commandTypeString
	 *            is the first word of the user command
	 */
	//@author a0118677r
	private CommandType determineCommandType(String commandTypeString) {
		if (commandTypeString == null)
			throw new Error(Language.getString("ERROR_UNRECOGNISED_COMMAND"));

		String commandToLowerCase = commandTypeString.toLowerCase();

		if (mappingOfCommandsToCommandTypes.containsKey(commandToLowerCase)) {
			return mappingOfCommandsToCommandTypes.get(commandToLowerCase);
		} else {
			return CommandType.INVALID;
		}
	}

	/**
	 * This method adds all the commands used in this program.
	 */
	//@author a0118677r
	private void addCommands() {
		mappingOfCommandsToCommandTypes.clear();
		// Put all command types to the map
		try {
			mappingOfCommandsToCommandTypes.put(
					Language.getString("COMMAND_ADD"), CommandType.ADD_TASK);
			mappingOfCommandsToCommandTypes.put(
					Language.getString("COMMAND_UPDATE"),
					CommandType.UPDATE_TASK);
			mappingOfCommandsToCommandTypes.put(
					Language.getString("COMMAND_DELETE"),
					CommandType.DELETE_TASK);
			mappingOfCommandsToCommandTypes.put(
					Language.getString("COMMAND_DISPLAY"),
					CommandType.SHOW_TASKS_IN_CLI);
			mappingOfCommandsToCommandTypes.put(
					Language.getString("COMMAND_EXIT"), CommandType.EXIT);
			mappingOfCommandsToCommandTypes.put(
					Language.getString("COMMAND_SEARCH"), CommandType.SEARCH);
			mappingOfCommandsToCommandTypes.put(
					Language.getString("COMMAND_LANGUAGE"),
					CommandType.CHANGE_LANGUAGE);
			mappingOfCommandsToCommandTypes.put(
					Language.getString("COMMAND_NOTIFY"), CommandType.NOTIFY);
			mappingOfCommandsToCommandTypes.put(
					Language.getString("COMMAND_SMS"), CommandType.SMS);
			mappingOfCommandsToCommandTypes.put(
					Language.getString("COMMAND_UNDO"), CommandType.UNDO);
		} catch (NullPointerException e) {
			throw new RuntimeException(
					"All commands were not found in language properties");
		}
	}

	//@author a0118677r
	private String removeFirstWord(String stringToStrip) {
		return stringToStrip.replaceFirst(getFirstWord(stringToStrip), "")
				.trim();
	}

	//@author a0118677r
	private String getFirstWord(String stringToStrip) {

		String[] splittedString = stringToStrip.split("\\s+");
		return splittedString[0];
	}

	//@author A0098803W
	/**
	 * This method checks if the list of serial numbers entered by the user is
	 * valid.
	 * 
	 * @param sentence
	 *            The user text.
	 * @return The list containing the extracted sequence of numbers or an empty
	 *         list.
	 * @throws CommandFormatException
	 */
	private ArrayList<String> checkValidSerialNumbers(String sentence)
			throws CommandFormatException {
		ArrayList<String> extractedSequence = Utilities
				.splitSequenceRange(sentence);

		if (!extractedSequence.isEmpty()) {
			String checkIndex = Utilities.checkValidDisplayIndex(
					extractedSequence, mappingOfDisplayedIndexToEventId);
			checkIndex = checkIndex.trim();
			if (checkIndex.isEmpty() == false) {

				return new ArrayList<String>();
			}

		}

		return extractedSequence;
	}

	//@author A0098803W
	/**
	 * This method extracts text from the <code>show</code> command executed by
	 * user.
	 * 
	 * @param sentence
	 *            User's text
	 * @return Modifies and returns the search text
	 */
	private String extractShowCommandFromUser(String sentence) {
		sentence.trim();
		String userCommand = "";
		if (sentence.startsWith("#")) {
			String[] splittedParameters = sentence.split("#");
			try {
				userCommand = splittedParameters[1].trim();
				return userCommand;
			} catch (ArrayIndexOutOfBoundsException e) {
				return "";
			}
		}

		return userCommand;
	}

	//@author A0098803W
	/**
	 * This method adds a new notification to the notification storage file.
	 * 
	 * @param sentence
	 *            User input text
	 * @throws DateFormatException
	 * @throws StorageException
	 * @throws CommandFormatException
	 */
	private void addNotification(String sentence) throws DateFormatException,
			StorageException, CommandFormatException {
		ArrayList<Notification> addedNotificationList = new ArrayList<Notification>();
		ArrayList<String> extractedNotifyParameterList = extractNotifyCommandFromUser(sentence);
		if (!extractedNotifyParameterList.isEmpty()) {
			String date = extractedNotifyParameterList.get(0);
			String dateFormat = extractedNotifyParameterList.get(1);
			String message = extractedNotifyParameterList.get(2);
			Notification addedNotification = logicAPI.add(date, dateFormat,
					message);
			addedNotificationList.add(addedNotification);
			mappingOfDisplayedIndexToNotificationObj.clear();
			mappingOfDisplayedIndexToNotificationObj.put(1, addedNotification);
			newNotification = true;
			System.out.println(Language
					.getString("SUCCESSFUL_NOTIFICATION_ADD"));
			showDetailedListOfNotification(addedNotificationList);
		}
	}

	//@author A0098803W
	/**
	 * This method will delete the last entered notification.
	 * 
	 * @throws StorageException
	 * @throws CommandFormatException
	 * 
	 * 
	 */
	private void undoAddNewNotification() throws StorageException,
			CommandFormatException {
		if (!newNotification) {
			throw new CommandFormatException(
					Language.getString("ERROR_NOTIFICATION_UNDO_FAILED"));
		} else {
			ArrayList<Notification> removedNotificationList = new ArrayList<Notification>();
			Notification removedNotification = logicAPI
					.delete(mappingOfDisplayedIndexToNotificationObj.get(1));
			removedNotificationList.add(removedNotification);
			newNotification = false;
			this.mappingOfDisplayedIndexToNotificationObj.clear();
			System.out.println(Language
					.getString("SUCCESSFUL_NOTIFICATION_DELETE"));
			showDetailedListOfNotification(removedNotificationList);
		}
	}

	//@author A0098803W
	/**
	 * This method shows details of notification entered by the user.
	 * 
	 * @param noticeList
	 *            The notification for display
	 */
	private void showDetailedListOfNotification(
			ArrayList<Notification> noticeList) {
		mappingOfDisplayedIndexToNotificationObj.clear();
		String noticeId;
		String timeToNotify;
		String message;

		String executionStatus = "";
		int counter = 0;
		for (Notification notice : noticeList) {
			counter++;
			noticeId = notice.getNotificationId();
			message = notice.getMessage();
			if (notice.isExecutionStatus() == true) {
				executionStatus = Language.getString("KEYWORD_YES");
			} else {
				executionStatus = Language.getString("KEYWORD_NO");
			}
			timeToNotify = Utilities.calendarToString(notice.getTimeToNotify(),
					Language.getString("SEARCH_DATE_TIME_FORMAT"));
			mappingOfDisplayedIndexToNotificationObj.put(counter, notice);

			System.out.printf(Language.getString("SHOW_LIST_TOP"));
			System.out.printf(Language.getString("SHOW_LIST_SERIAL_NUMBER"),
					counter);
			System.out.printf(Language.getString("SHOW_LIST_NOTICE_ID"),
					noticeId);
			System.out.printf(Language.getString("SHOW_LIST_NOTICE_DATETIME"),
					timeToNotify);
			System.out.printf(Language.getString("SHOW_DESCRIPTION"), message);
			System.out.printf(Language.getString("SHOW_FOOTER"));
		}

	}

	//@author A0098803W
	/**
	 * This method extracts the date, the date's format and the message for the
	 * notification.
	 * 
	 * @param sentence
	 *            User input text
	 * @return The list containing the date, the date's format and the message
	 *         for the notification.
	 */
	private ArrayList<String> extractNotifyCommandFromUser(String sentence) {
		sentence.trim();
		ArrayList<String> userCommand = new ArrayList<String>();
		if (sentence.startsWith("@")) {
			try {
				String[] splittedParameters = sentence.split(" ");
				String date = splittedParameters[0].trim();
				if (date.length() == 1) {
					throw new CommandFormatException(
							Language.getString("ERROR_UNRECOGNISED_COMMAND"));
				}
				date = date.substring(1, date.length());
				String msg = "";

				String dateFormat = Utilities.getDateFormat(date);
				if (dateFormat.isEmpty()) {
					throw new CommandFormatException(
							Language.getString("ERROR_WRONG_DATE_FORMAT"));
				} else {

					for (int i = 1; i < splittedParameters.length; i++) {
						msg += splittedParameters[i] + " ";
					}
					userCommand.add(0, date);
					userCommand.add(1, dateFormat);
					userCommand.add(2, msg);

				}

				return userCommand;
			} catch (ArrayIndexOutOfBoundsException | CommandFormatException e) {
				System.out.println(e.getMessage());
				return userCommand;
			}
		}
		return userCommand;

	}

	//@author A0098803W
	/**
	 * This method updates the messaging gateway for the program.
	 * 
	 * @param sentence
	 *            User input text.
	 * @throws StorageException
	 * @throws CommandFormatException
	 */
	private void updateMessageGateway(String sentence)
			throws CommandFormatException, StorageException {
		logicAPI.updateGateway(sentence);
		System.out.printf(Language.getString("SUCCESSFUL_GATEWAY_ADD"),
				sentence);
		System.out.println(Language.getString("SAMPLE_GATEWAY"));
	}
}
